package ruc.utils;

import cn.hutool.core.io.FileUtil;
import cn.hutool.core.lang.Console;
import cn.hutool.core.text.csv.*;
import cn.hutool.core.util.CharsetUtil;
import com.fasterxml.uuid.Generators;
import ruc.Consts.constant;
import ruc.disorder.PoissonDistribution;

import java.io.*;
import java.util.*;

public class IOUtils {
    public static String convert(String s) {
        return s.contains(".") ? s.substring(0, s.indexOf(".")) : s;
    }

    public static String[] GetData() {
        ArrayList<String> arrList = new ArrayList<>();
        CsvReader reader = CsvUtil.getReader();
        for (int idx = 0; idx < 3; idx++) {
            //从文件中读取CSV数据
            CsvData data = null;
            try {
                data = reader.read(new FileReader(constant.GetReadeFilePath(0)));
            } catch (FileNotFoundException e) {
                e.printStackTrace();
            }
            List<CsvRow> rows = data.getRows();

            Random ran = new Random();
            //cpu_usage = 6, disk_usage = 9, memory_usage = 13
            //第一行是title过滤掉，一个broker有2w左右的数据
            for (CsvRow row : rows) {
                StringBuffer sb = new StringBuffer();
                List<String> rawList = row.getRawList();
                if (rawList.get(0).equals("null") || rawList.get(6).equals("null") || rawList.get(9).equals("null") || rawList.get(13).equals("null")) {
                    continue;
                }

                sb.append(rawList.get(0), 0, 13).append(constant.Delimiter); // timestamp是13位
                sb.append(Generators.timeBasedGenerator().generate()).append(constant.Delimiter);
                sb.append(constant.server[ran.nextInt(constant.server.length)]).append(constant.Delimiter);
                sb.append(Generators.timeBasedGenerator().generate()).append(constant.Delimiter);
                sb.append(convert(rawList.get(6))).append(constant.Delimiter);
                sb.append(convert(rawList.get(9))).append(constant.Delimiter);
                sb.append(convert(rawList.get(13)));

                //1629877680000:8a6b0a73-7363-11ec-8826-711bd9868a33:SERVICE.BMS:8a6b0a74-7363-11ec-8826-f99a8e3b82b1:0:1:74

                arrList.add(sb.toString());
            }
        }

        return arrList.toArray(new String[0]);
    }

    //mode 0:批乱序 1:泊松乱序     batchSize: 数据量
    public static String[] GetDisorderData(int mode, int batchSize) {
        long start = System.currentTimeMillis();
        switch (mode) {
            case 0:
                return BatchDisorder(start, batchSize);
            case 1:
                return PoissonDisorder(start, batchSize);
            default:
                throw new IllegalArgumentException("Unsupported  disorder mode !");
        }

    }

    private static String[] BatchDisorder(long start, int batchSize) {
        PriorityQueue<String> queue = new PriorityQueue<>((o1, o2) -> {
            int a = ValueUtils.getIntByRandom(100);
            int b = ValueUtils.getIntByRandom(100);
            return (int) ((a - b) * (Long.parseLong(o1.split(constant.Delimiter)[0]) -
                    Long.parseLong(o2.split(constant.Delimiter)[0])));
        });
        long timestamp = start;
        StringBuilder sb = new StringBuilder();
        for (int i = 0; i < batchSize; i++) {
            sb.append(timestamp += 60000).append(constant.Delimiter);//时间间隔1min
            sb.append(Generators.timeBasedGenerator().generate()).append(constant.Delimiter);
            sb.append(constant.server[ValueUtils.getIntByRandom(constant.server.length)]).append(constant.Delimiter);
            sb.append(Generators.timeBasedGenerator().generate()).append(constant.Delimiter);
            sb.append(ValueUtils.getIntByRandom(100)).append(constant.Delimiter);
            sb.append(ValueUtils.getIntByRandom(100)).append(constant.Delimiter);
            sb.append(ValueUtils.getIntByRandom(100)).append(constant.Delimiter);
            queue.add(sb.toString());
            sb.setLength(0);
        }
        String[] data = new String[queue.size()];
        for (int i = 0; i < data.length; i++) {
            data[i] = queue.poll();
        }
        return data;
    }

    private static String[] PoissonDisorder(long start, int batchSize) {
        TreeMap<Integer, Integer> poissonMap = PoissonDistribution.getPoissonMap(batchSize);
        StringBuilder sb = new StringBuilder();
        String[] data = new String[batchSize];
        int k = 0;
        for (int delta : poissonMap.keySet()) {
            int count = poissonMap.get(delta);
            for (int i = 0; i < count; i++) {
                sb.append(start + delta * 10000L).append(constant.Delimiter);//时间间隔为delta*10000L 10秒
                sb.append(Generators.timeBasedGenerator().generate()).append(constant.Delimiter);
                sb.append(constant.server[ValueUtils.getIntByRandom(constant.server.length)]).append(constant.Delimiter);
                sb.append(Generators.timeBasedGenerator().generate()).append(constant.Delimiter);
                sb.append(ValueUtils.getIntByRandom(100)).append(constant.Delimiter);
                sb.append(ValueUtils.getIntByRandom(100)).append(constant.Delimiter);
                sb.append(ValueUtils.getIntByRandom(100)).append(constant.Delimiter);
                data[k++] = sb.toString();
                sb.setLength(0);
            }
        }
        return data;
    }


    public static void WriteData(String filePath, String[] data) {
        CsvWriter writer = CsvUtil.getWriter(filePath, CharsetUtil.CHARSET_UTF_8, true); // append的方式写文件
        writer.write(data);
    }
}
